package org.jeecg.modules.ncmeapis.network.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.config.swagger.BusinessApi;
import org.jeecg.modules.ncmeapis.network.entities.entity.NetworkPath;
import org.jeecg.modules.ncmeapis.network.entities.entity.params.*;
import org.jeecg.modules.ncmeapis.network.entities.entity.vo.PathWithPerm;
import org.jeecg.modules.ncmeapis.network.entity.ChunkFileParam;
import org.jeecg.modules.ncmeapis.network.entity.ChunkFileParamPre;
import org.jeecg.modules.ncmeapis.network.enums.FileSource;
import org.jeecg.modules.ncmeapis.network.enums.PathType;
import org.jeecg.modules.ncmeapis.network.enums.UploadPath;
import org.jeecg.modules.ncmeapis.network.service.INetworkPathService;
import org.jeecg.modules.ncmeapis.network.service.INetworkService;
import org.jeecg.modules.ncmeapis.network.service.impl.UploadServiceImpl;
import org.jeecg.modules.system.controller.CommonController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.List;
import java.util.Map;

/**
 *
 */
@Api(tags = "文件管理-前端")
@RestController
@RequestMapping("/network")
//@BusinessApi
@Slf4j
public class NetworkDiskController {

    @Autowired
    private UploadServiceImpl uploadService;
    @Autowired
    private INetworkPathService networkPathService;
    @Autowired
    private INetworkService networkService;
    @Autowired
    private CommonController commonController;

    //=================================文件读取相关=================================

    @AutoLog(value = "获取文件目录树")
    @ApiOperation(value = "获取文件目录树的一层", notes = "pid不传则获权限内的根目录")
    @GetMapping(value = "/getTree")
    public Result<List<PathWithPerm>> getTree(@RequestParam(name = "pid", required = false) String pid, @RequestParam(name = "showFile", defaultValue = "true") boolean showFile) {
        List<PathWithPerm> pathWithPerms = networkService.list(pid, showFile);
        return Result.ok(pathWithPerms);
    }

    @AutoLog(value = "预览文件")
    @ApiOperation(value = "预览文件", notes = "")
    @GetMapping(value = "/preview")
    public Result<?> preview(@RequestParam(name = "pathId") String pathId) {
        networkService.preview(pathId);
        return Result.ok("预览成功");
    }

    @AutoLog(value = "下载文件")
    @ApiOperation(value = "下载文件", notes = "")
    @GetMapping(value = "/download")
    public ResponseEntity<?> download(@RequestParam(name = "pathId") String pathId) {
        return networkService.download(pathId);
    }

    //=================================文件修改相关=================================

    @AutoLog(value = "编辑文件")
    @ApiOperation(value = "编辑文件", notes = "只校验权限,为在线编辑预留")
    @PutMapping(value = "/edit")
    public Result<?> edit(@RequestBody @Validated EditParam editParam) {
        networkService.edit(editParam.getPathId());
        return Result.ok("编辑成功");
    }

    @AutoLog(value = "重命名文件或文件夹")
    @ApiOperation(value = "重命名文件或文件夹", notes = "")
    @PutMapping(value = "/rename")
    public Result<?> rename(@RequestBody @Validated RenameParam renameParam) {
        networkService.rename(renameParam.getPathId(), renameParam.getNewName());
        return Result.ok("重命名成功");
    }

    @AutoLog(value = "移动文件")
    @ApiOperation(value = "移动文件", notes = "")
    @PutMapping(value = "/move")
    public Result<?> move(@RequestBody @Validated MoveParam moveParam) {
        networkService.move(moveParam.getPathId(), moveParam.getTargetId());
        return  Result.ok("移动成功");
    }

    //=================================文件上传相关=================================

    @AutoLog(value = "检查文件或文件夹重名")
    @ApiOperation(value = "检查重名", notes = "【type】：folder/file")
    @GetMapping(value = "/checkName")
    public Result<?> checkName(@RequestParam @Validated CheckNameParam checkNameParam) {
        if (checkNameParam.getType().equals(PathType.FOLDER)) {
            networkService.checkNameRepeats(checkNameParam.getPathId(), checkNameParam.getName(), PathType.FOLDER);
        } else if (checkNameParam.getType().equals(PathType.FILE)) {
            networkService.checkNameRepeats(checkNameParam.getPathId(), checkNameParam.getName(), PathType.FILE);
        } else throw new RuntimeException("未知目录类型");
        return Result.OK("ok");
    }

    @AutoLog(value = "新建文件夹")
    @ApiOperation(value = "新建文件夹", notes = "")
    @PostMapping(value = "/mkdir")
    public Result<?> mkdir(@RequestBody @Validated MkdirParam mkdirParam) {
        networkService.checkNameRepeats(mkdirParam.getPathId(), mkdirParam.getNewName(), PathType.FOLDER);
        networkService.mkdir(mkdirParam.getNewName(), mkdirParam.getPathId());
        return Result.OK("新建文件夹成功");
    }

    @AutoLog(value = "简单上传文件")
    @ApiOperation(value = "简单上传文件", notes = "")
    @PostMapping(value = "/upload")
    public Result<?> upload(@RequestBody @Validated SimUploadParam uploadParam) throws Exception {
        networkService.checkNameRepeats(uploadParam.getTargetId(), uploadParam.getFile().getOriginalFilename(), PathType.FILE);
        NetworkPath parentPath = networkPathService.getById(uploadParam.getTargetId());
        Result<?> upload = commonController.upload(UploadPath.ROOT + parentPath.getPath(), uploadParam.getFile());
        networkService.upload(uploadParam.getTargetId(), upload.getMessage(), FileSource.JEECG_API);
        return upload;
    }

    @AutoLog(value = "简单上传文件(swagger)")
    @ApiOperation(value = "简单上传文件(swagger)", notes = "")
    @PostMapping(value = "/upload2")
    public Result<?> upload(@RequestPart MultipartFile file, @RequestPart String targetId) throws Exception {
        return upload(new SimUploadParam(file, targetId));
    }

    @AutoLog(value = "切片断点续传-预上传")
    @ApiOperation(value = "切片断点续传-预上传", notes = "")
    @GetMapping("/upload/continue")
    Result<?> continueUploadPre(@RequestBody @Validated ChunkFileParamPre param) {
        //检查文件重名
        networkService.checkNameRepeats(param.getPathId(), param.getFileName(), PathType.FILE);
        //预上传
        Map<String, Object> map = uploadService.continueUploadPre(param);
        return Result.ok(map);
    }

    @AutoLog(value = "切片断点续传-切片上传")
    @ApiOperation(value = "切片断点续传-切片上传", notes = "")
    @PostMapping("/upload/continue")
    Result<?> continueUpload(@RequestBody @Validated ChunkFileParam fileParam) throws Exception {
        Map<String, Object> map = uploadService.continueUpload(fileParam, (networkFile, file) -> {
            String fileUrl = networkFile.getService() + networkFile.getType() + File.separator + networkFile.getStoreName();
            networkService.upload(fileParam.getPathId(), fileUrl, FileSource.JEECG_API);
        });
        return Result.ok(map);
    }

    //=================================文件删除相关=================================

    @AutoLog(value = "删除文件")
    @ApiOperation(value = "删除文件", notes = "")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestBody @Validated DeleteParam deleteParam) {
        networkService.delete(deleteParam.getPathId());
        return Result.OK("删除成功");
    }

}
